package com.zjpavt.client.extenddevice;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.zjpavt.client.Connection;
import com.zjpavt.client.command.CommandPusher;
import com.zjpavt.client.enums.ExtendDeviceEnum;
import com.zjpavt.client.hal.ExtendDeviceManager;
import com.zjpavt.client.hal.LoopManager;
import com.zjpavt.client.nativemethod.JnIMethod;
import com.zjpavt.client.util.Consts;
import com.zjpavt.client.util.ProcessUtil;
import com.zjpavt.client.util.PropertiesUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 没有发现设备的虚拟设备（假装有一个设备）
 * @author zyc
 */
@Slf4j
public class WithoutExtendDevice extends AbstractExtendDevice implements IExtendDevice {
    public static final ScheduledThreadPoolExecutor SCHEDULED_THREAD_POOL_EXECUTOR = new ScheduledThreadPoolExecutor(1);
    private static final Pattern VOLTAGE_CURRENT_PATTERN =
        Pattern.compile("<CIRCUIT_CURRENT_DATA_CH[0-9]{1,2}_\\[A_(?<A>\\d{1,3}\\.\\d)]\\[B_(?<B>\\d{1,3}\\.\\d)]\\[C_(?<C>\\d{1,3}\\.\\d)]" +
                        "(?:\\[[0-9]{1,3}/[0-9.]{1,5}/[01]])*>");

    public WithoutExtendDevice(int extendNum) {
        super(extendNum,ExtendDeviceEnum.WITHOUT_DEVICE);
        reFindExtendDevice();
    }

    /**
     * 超时未检测到设备,需要定期查询端口
     */
    private synchronized void  reFindExtendDevice() {
        SCHEDULED_THREAD_POOL_EXECUTOR.schedule(()-> {
            checkAsNormalDevice();
            //检测电流电压告警
            // checkAsAlarmDevice() ;
        },20, TimeUnit.SECONDS);
    }

    /**
     * 作为电流电压检测模块确认
     */
    private  void checkAsElect() {
        String electInformation = "<AT_CHECK0_ELECT_12_A_B_C_A_B_C_A_B_C_A_B_C>";
        String information = JnIMethod.sendMessage2ExtendDeviceByRs485DefaultBanudRate(getExtendNum(), electInformation, 200);
//      没有收到确认
        if (information == null) {
            reFindExtendDevice();
            return;
        }
        Matcher matcher = AcDetector.VOLTAGE_CURRENT_PATTERN.matcher(information);
        if (matcher.matches()) {
            AcDetector acDetector = new AcDetector(12,getExtendNum());
            ExtendDeviceManager.getInstance().addDevice(getExtendNum(),acDetector,true);
        } else {
            reFindExtendDevice();
            log.error("unknown device status");
        }
    }

    /**
     * 作为远程抄表模块确认
     */
    @Deprecated
    private void checkAsPower() {
        String electInformation = "<AT_CHECK0_POWER>";
        String information = JnIMethod.sendMessage2ExtendDeviceByRs485DefaultBanudRate(getExtendNum(), electInformation, 200);
//      没有收到确认
        if (information == null) {
            reFindExtendDevice();
            return;
        }
        Matcher matcher = PowerRemoteReader.POWER_PATTERN.matcher(information);
        if (matcher.matches()) {
            PowerRemoteReader powerRemoteReader = new PowerRemoteReader(getExtendNum());
            ExtendDeviceManager.getInstance().addDevice(getExtendNum(),powerRemoteReader,true);
        } else {
            log.error("unknown device status");
            reFindExtendDevice();
        }
    }
    /**
     * 重新确认设备,作为通用设备确认
     */
    private void checkAsNormalDevice() {
        AbstractExtendDevice extendDevice = ExtendDeviceManager.getInstance().findExtendDevice(getExtendNum(),false);
        AbstractExtendDevice devcie = ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(getExtendNum());
        //if(extendDevice != null && !devcie.getDeviceType().equals(extendDevice.getDeviceType())) {
        if(extendDevice != null  && (!devcie.getDeviceType().equals(extendDevice.getDeviceType()) || ExtendDeviceEnum.isGpsLigthDevice(extendDevice.getDeviceType()))) {
            ExtendDeviceManager.getInstance().addDevice(getExtendNum(),extendDevice,true);
            devcie.setTag(0);
        } else if(extendDevice == null && !devcie.getDeviceType().equals(ExtendDeviceEnum.WITHOUT_DEVICE)) {
            if(devcie.getTag() >2) {
                //出现内存溢出问题时，重新启动服务器
                if(getExtendNum()==0) {
                    try {
                        ProcessUtil.runCommandWait("reboot");
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                ExtendDeviceManager.getInstance().removeDeviceInfoMap(getExtendNum());
                extendDevice = new AbstractExtendDevice(getExtendNum(),ExtendDeviceEnum.WITHOUT_DEVICE) {};
                ExtendDeviceManager.getInstance().setExtendNumDeviceMap(getExtendNum(),extendDevice);
                if(ExtendDeviceManager.getInstance().getLoopExtendDeviceMap().get(getExtendNum()) != null) {
                    ExtendDeviceManager.getInstance().getLoopExtendDeviceMap().remove(getExtendNum());
                    LoopManager.getInstance().init();
                }
                if(ExtendDeviceManager.getInstance().getVoltageAndCurrentExtendDeviceMap().get(getExtendNum()) != null)
                    ExtendDeviceManager.getInstance().getVoltageAndCurrentExtendDeviceMap().remove(getExtendNum());
                ExtendDeviceManager.getInstance().removeDeviceFromTypeMap((IExtendDevice)devcie,devcie.getDeviceType());
                devcie.setTag(0);
                ExtendDeviceManager.getInstance().addDevice(getExtendNum(),extendDevice,true);
            } else {
                devcie.setTag(devcie.getTag()+1);
            }
        } else {
            devcie.setTag(0);
        }
        reFindExtendDevice();
    }


    /**
     * 设备告警
     */
    private void checkAsAlarmDevice() {
        AbstractExtendDevice acDetector = ExtendDeviceManager.getInstance().findExtendDevice(getExtendNum(),false);
        AcDetector extendDevice= (AcDetector)acDetector;
        if(extendDevice != null && extendDevice.getDeviceType().getDeviceName().equals("ELECT")) {
            try {
                Map<String, String> voltageMap = new HashMap<String,String>();
                List<String[]>  voltageList = new ArrayList<String[]>();
                Map<String,String> voltageMessageMap = new HashMap<String,String>();
                List<String[]> voltageMessageList =  new ArrayList<String[]>();
                String elec_channel_is_testing = PropertiesUtil.getPropertiesDefault(Consts.KEY_ELEC_CHANNEL_IS_TESTING);
                String ecitStr[] = elec_channel_is_testing.split("");
                //是否发告警指令为1发送  为0 不发送
                if(null != elec_channel_is_testing && elec_channel_is_testing.contains("1")) {
                    //检测是否有异常
                    String phaseEveryLoop = extendDevice.getPhaseEveryLoop().toString();
                    phaseEveryLoop= phaseEveryLoop.substring(1, phaseEveryLoop.length()-1).replace(", ", "_");
                    String checkDeviceInfo = JnIMethod.sendMessage2ExtendDeviceByRs485(115200, getExtendNum(), "<AT_CHECK0_ELECT_"+extendDevice.getLoopNum()+"_"+phaseEveryLoop+">", 500);

                    String info = checkDeviceInfo.substring(7,checkDeviceInfo.length()-1);
                    info = info.substring(1,info.length()-1);
                    String infoStr[] = info.split("]\\[");
                    StringBuffer  voltageN = new StringBuffer();
                    voltageN.append("<N_");
                    for(String value :infoStr) {
                        String[] infos = value.split("_");
                        Integer keyInt = Integer.valueOf(infos[0]);
                        String str = keyInt+"_"+infos[1];
                        voltageN.append("[").append(str).append("]");
                    }
                    voltageN.append(">");
                    for(int i = 0; i <infoStr.length; i++) {
                        String []_info = infoStr[i].split("_");
                        String []listInfo =  {_info[0], _info[1].substring(6, _info[1].length())};

                        voltageList.add(listInfo);
                        voltageMap.put(_info[0], _info[1].substring(6, _info[1].length()));
                    }

                    for(String[]vol :voltageList) {
                        log.debug(vol[0]+vol[1]);
                        if(ecitStr[Integer.valueOf(vol[0])-1].equals("1") &&voltageMap.get(vol[0]).equals("00.0") ) {

                            String []listInfo =  {Integer.valueOf(vol[0]).toString(), "1"};
                            voltageMessageList.add(listInfo);
                            voltageMessageMap.put(Integer.valueOf(vol[0]).toString(), "1");


                        } else {
                            voltageMessageMap.put(Integer.valueOf(vol[0]).toString(), "0");
                            String []listInfo =  {Integer.valueOf(vol[0]).toString(), "0"};
                            voltageMessageList.add(listInfo);
                        }
                    }
                    StringBuffer  voltageR = new StringBuffer();
                    voltageR.append("<R_");
                    for(String[]vol :voltageMessageList) {
                        voltageR.append(vol[1]);
                    }
                    voltageR.append("_ALARM>");
                    //发送告警指令
                    CommandPusher.AlarmPush(Connection.getInstance(), voltageR.toString());
                    //String checkAsAlarmInfo = JnIMethod.sendMessage2ExtendDeviceByRs485(115200, getExtendNum(), voltageR.toString(), 500);
                    //log.debug(checkAsAlarmInfo);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }


    @Override
    public ExtendDeviceEnum getDeviceType() {
        return super.getDeviceType();
    }

    @Override
    public void disConnected() {

    }

    @Override
    public void reCheck() {

    }
}
